package dongtaidaili;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//对比Test  这才是真正的动态代理


public class Test2 {
    public static void main(String[] args) {
        //这里注意不是final类型在下面将不能被内部类引用

        try {
              //通过反射动态加载需要的类   先运行后编译
                 Class clazz=Class.forName("dongtaidaili.MyActor");
                 Object o = clazz.newInstance();


            //这就是在创建代理对象，第一个参数类加载器；第二个参数被代理对象实现的接口，好告知代理对象它需要具备哪些行为；第三个参数就是我们进行增强的代码

            IActor proxyActor = (IActor) Proxy.newProxyInstance(clazz.getClassLoader(),
                    clazz.getInterfaces(), new InvocationHandler() {

                        @Override
                        //proxy代表代理对象，method表示执行的方法对象，args表示参数数组。被代理对象每个方法执行时都会过这个invoke方法
                        public Object invoke(Object proxy, Method method, Object[] args)
                                throws Throwable {
                            int money = (int) args[0];
                            if("perform".equals(method.getName())){
                                if(money>10000)
                                    method.invoke(o, args);
                            }else if("dangerPerform".equals(method.getName())){
                                if(money>50000)
                                    method.invoke(o, args);
                            }
                            return null;
                        }
                    });
            proxyActor.perform(10001, "hahaha");
            proxyActor.dangerPerform(50001);
        } catch (Exception e) {
            e.printStackTrace();
        }




    }


}

/*两种动态代理的最大的区别是：
JDK动态代理要求被代理对象必须基于接口来实现。动态代理类和被代理类必须继承同一个接口。动态代理只能对接口中声明的方法进行代理。
对那些没有实现接口的bean。JDK动态代理无法代理。而CGLib通过继承被代理类的方式实现代理。

作者：RyanLee_
链接：https://www.jianshu.com/p/95eaae0a363f
来源：简书
著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。*/